package com.kool.kadmin.common.intercept;

import com.kool.kadmin.common.bean.ErrorVo;
import com.kool.kadmin.common.bean.Result;
import com.kool.kadmin.common.constant.ErrorCode;
import com.kool.kadmin.common.exception.AppException;
import com.kool.kadmin.common.util.ResultUtil;
import com.kool.kadmin.common.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 应用异常捕获
 *
 * @author luyu
 */
@ControllerAdvice
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 业务异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(AppException.class)
    public Result appExceptionHandler(AppException e) {
        if (ErrorCode.BUSINESS_ERROR.getCode().equals(e.getErrorCode())) {
            log.debug(e.getMessage(), e);
        } else {
            log.error(e.getMessage(), e);
        }
        return new Result().setCode(e.getErrorCode()).setMessage(e.getMessage());
    }

    /**
     * 请求参数校验
     *
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result badRequestHandler(MethodArgumentNotValidException e) {
        log.debug(e.getMessage(), e);

        List<ErrorVo> errors = e.getBindingResult().getAllErrors().stream().map(objectError -> {
            ErrorVo errorVo = new ErrorVo();
            errorVo.setCode(objectError.getCodes()[0]).setMsg(objectError.getDefaultMessage());
            return errorVo;
        }).collect(Collectors.toList());

        return ResultUtil.error(ErrorCode.REQ_PARAM_ERROR, errors, e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
    }

    /**
     * 请求json格式异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public Result jsonParseErrorHandler(HttpMessageNotReadableException e) {
        String errUid = StringUtil.getUUID();
        log.error(errUid, e);
        return ResultUtil.error(ErrorCode.REQ_PARAM_ERROR, "json格式错误，异常码：" + errUid);
    }

    /**
     * 插入重复数据，违反唯一性约束
     *
     * @param e
     * @return
     */
    @ExceptionHandler(DuplicateKeyException.class)
    public Result duplicateKeyHandler(DuplicateKeyException e) {
        String errUid = StringUtil.getUUID();
        log.error(errUid, e);
        return ResultUtil.error(ErrorCode.DUPLICATE_KEY_ERROR, e.getCause().getMessage() + "，异常码：" + errUid);
    }

    /**
     * 其它异常
     *
     * @param t
     * @return
     */
    @ExceptionHandler(Throwable.class)
    public Result otherExceptionHandler(Throwable t) {
        String errUid = StringUtil.getUUID();
        log.error(errUid, t);
        return ResultUtil.error(ErrorCode.SYSTEM_ERROR, errUid);
    }

}
